/*
    KDE Plugin for 3D Office Environment
    Copyright (C) 2011  Till Merker

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "OfficeEnvConfigForm.h"

#include <kwineffects.h>

#include <kconfiggroup.h>
#include <KDE/KActionCollection>
#include <kaction.h>

#include <QtGui/QVBoxLayout>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>

namespace KWin
{

KWIN_EFFECT_CONFIG_MULTIPLE(officeenv,
  KWIN_EFFECT_CONFIG_SINGLE(officeenv, OfficeEnvConfig)
)

OfficeEnvConfigForm::OfficeEnvConfigForm(QWidget* parent) : QWidget(parent)
{
  setupUi(this);
}

OfficeEnvConfig::OfficeEnvConfig(QWidget* parent, const QVariantList& args)
    :   KCModule( EffectFactory::componentData(), parent, args )
    {
    m_ui = new OfficeEnvConfigForm( this );

    QVBoxLayout* layout = new QVBoxLayout( this );

    layout->addWidget( m_ui );

    // Shortcut config. The shortcut belongs to the component "kwin"!
    m_actionCollection = new KActionCollection( this, KComponentData("kwin") );

    m_actionCollection->setConfigGroup( "OfficeEnv" );
    m_actionCollection->setConfigGlobal( true );

    KAction* a = (KAction*) m_actionCollection->addAction( "ShowOfficeEnv" );
    a->setText( i18n( "Activate 3D Office Environment" ));
    a->setProperty( "isConfigurationAction", true );
    a->setGlobalShortcut( KShortcut( Qt::ALT + Qt::Key_Escape ));
    
    connect( a, SIGNAL( triggered(bool) ), this, SLOT( toggleActive() ));
    connect( a, SIGNAL( globalShortcutChanged(QKeySequence) ), this, SLOT( globalShortcutChanged(QKeySequence)));     
 
    m_ui->shortcutEditor->addCollection( m_actionCollection );

    connect( m_ui->shortcutEditor, SIGNAL( keyChange() ), this, SLOT( changed() ));

    /* Scan common locations for offices */
    scanForOffices(std::string(INSTALL_PREFIX) + "/share/officeenv");   
    scanForOffices(std::string(getenv("HOME")) + "/officeenv");   
    scanForOffices("/usr/local/share/officeenv");   
    scanForOffices("/usr/share/officeenv");
    
    connect( m_ui->officeCombo, SIGNAL( currentIndexChanged( int )), this, SLOT( changed() ));
    
    load();
    }

OfficeEnvConfig::~OfficeEnvConfig()
    {
    // If save() is called undoChanges() has no effect
    m_ui->shortcutEditor->undoChanges();
    }
    
void OfficeEnvConfig::scanForOffices(std::string dirName) { 
    /* Find offices under dirName. An office is a subdirectory with either an "office.bsp" or "office.scene" in it */
    if(DIR *dir = opendir(dirName.c_str())) {
	for(struct dirent *dirent = readdir(dir); dirent; dirent = readdir(dir)) {	    
	    struct stat statbuf;
	    if((stat((dirName + "/" + dirent->d_name).c_str(), &statbuf) == 0) && S_ISDIR(statbuf.st_mode)) {
		std::string fileNameBSP = dirName + "/" + dirent->d_name + "/office.bsp";
		std::string fileNameSCENE = dirName + "/" + dirent->d_name + "/office.scene";
		if(stat(fileNameBSP.c_str(), &statbuf) == 0) {
		    m_ui->officeCombo->addItem(QString(dirent->d_name), QString(fileNameBSP.c_str()));		    
		} else if(stat(fileNameSCENE.c_str(), &statbuf) == 0) {
		    m_ui->officeCombo->addItem(QString(dirent->d_name), QString(fileNameSCENE.c_str()));		
		}
	    }
	}	
	closedir(dir);
    }
}

void OfficeEnvConfig::load()
    {
    KCModule::load();

    KConfigGroup conf = EffectsHandler::effectConfig( "OfficeEnv" );
    
    QString selectedOffice = conf.readEntry("SelectedOffice", "Base");
    int index = m_ui->officeCombo->findText(selectedOffice);    
    m_ui->officeCombo->setCurrentIndex(index);

    emit changed(false);
    }

void OfficeEnvConfig::save()
    {
    KCModule::save();

    KConfigGroup conf = EffectsHandler::effectConfig( "OfficeEnv" );

    conf.writeEntry("SelectedOffice", m_ui->officeCombo->currentText());
    conf.writeEntry("SelectedOfficeFile", m_ui->officeCombo->itemData(m_ui->officeCombo->currentIndex()));

    m_ui->shortcutEditor->save();

    conf.sync();

    emit changed(false);
    EffectsHandler::sendReloadMessage( "officeenv" );
    }

void OfficeEnvConfig::defaults()
    {
    m_ui->shortcutEditor->allDefault();
    int index = m_ui->officeCombo->findText("Base");  
    m_ui->officeCombo->setCurrentIndex(index);
    emit changed(true);
    }

} // namespace

//#include "OfficeEnvConfigForm.moc"
